#include "../logs/gjclog.h"
#include <chrono>

void bench(const std::string &logger_name, size_t thread_count, size_t msg_count, size_t msg_len)
{
    // 获取日志器
    gjclog::Logger::ptr logger = gjclog::getLogger(logger_name);
    if(logger.get() == nullptr)
    {
        return;
    }
    std::cout << "测试日志: " << msg_count << " 条, 总大小: " << (msg_count * msg_len) / 1024 << " KB\n";
    // 组织指定长度日志消息
    std::string msg(msg_len - 1, 'A');
    // 创建指定数量线程
    std::vector<std::thread> threads;
    std::vector<double> cost_arry(thread_count);
    size_t msg_per_thread = msg_count / thread_count;   // 每个线程输出的日志数量
    for(int i = 0; i < thread_count; i++)
    {
        threads.emplace_back([&, i](){
            // 线程函数内部开始计时（因为只计算写日志消耗的时间）
            auto start = std::chrono::high_resolution_clock::now();
            // 循环写日志
            for(int j = 0; j < msg_per_thread; j++)
            {
                logger->fatal("%s", msg.c_str());
            }
            // 结束计时
            auto end = std::chrono::high_resolution_clock::now();
            // 计算当前线程写日志消耗的事件
            std::chrono::duration<double> cost = end - start;
            cost_arry[i] = cost.count();
            std::cout << "线程" << i << ": " << "\t输出数量: " << msg_per_thread << ", 耗时: " << cost.count() << "s" << std::endl;
        });
    }
    for(int i = 0; i < thread_count; i++)
    {
        threads[i].join();
    }
    // 计算总耗时
    double max_cost = cost_arry[0];
    for(int i = 0; i < thread_count; i++)
    {
        max_cost = max_cost < cost_arry[i] ? cost_arry[i] : max_cost;
    }
    size_t msg_per_sec = msg_count / max_cost;                          // 每秒输出的日志数量
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);    // 每秒输出的日志大小kb

    // 输出打印
    std::cout << "\t总耗时: " << max_cost << " s\n";
    std::cout << "\t每秒输出日志数量: " << msg_per_sec << " 条\n";
    std::cout << "\t每秒输出日志大小: " << msg_per_sec << " KB\n";
}

// 同步日志测试
void sync_bench()
{
    std::unique_ptr<gjclog::LoggerBuilder> builder(new gjclog::GlobalLoggerBuilder());
    builder->bulidLoggerName("sync_logger");
    builder->buildLoggerLevel(gjclog::LogLevel::value::DEBUG);
    builder->buildFormatter("[%c][%f:%l][%p]%m%n");
    builder->buildLoggerType(gjclog::LoggerType::LOGGER_SYNC);
    builder->buildSink<gjclog::FileSink>("./logfile/sync.log");
    builder->build();
    // bench("sync_logger", 1, 1000000, 100);      // 单线程写1000000条日志，每条日志长100字节
    bench("sync_logger", 3, 1000000, 100);      // 多线程写1000000条日志，每条日志长100字节
}

// 异步日志测试
void async_bench()
{
    std::unique_ptr<gjclog::LoggerBuilder> builder(new gjclog::GlobalLoggerBuilder());
    builder->bulidLoggerName("async_logger");
    builder->buildLoggerLevel(gjclog::LogLevel::value::DEBUG);
    builder->buildFormatter("[%c][%f:%l][%p]%m%n");
    builder->buildLoggerType(gjclog::LoggerType::LOGGER_ASYNC);
    builder->buildEnableUnSafeAsync();  // 非安全模式
    builder->buildSink<gjclog::FileSink>("./logfile/async.log");
    builder->build();
    // bench("async_logger", 1, 2000000, 100);      // 单线程写1000000条日志，每条日志长100字节
    bench("async_logger", 3, 2000000, 100);      // 多线程写2000000条日志，每条日志长100字节
}

int main()
{
    async_bench();
    return 0;
}